package meiyunting.shiwuzhaoling_gatway.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * 全局异常处理器
 * 处理网关中的所有异常
 */
@Slf4j
@Order(-1)
@Component
public class GlobalExceptionHandler implements ErrorWebExceptionHandler {

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        ServerHttpResponse response = exchange.getResponse();
        
        // 设置响应的Content-Type
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        
        // 根据异常类型设置不同的HTTP状态码
        if (ex instanceof NotFoundException) {
            response.setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
            return response.writeWith(Mono.just(getResponseBuffer(response, "服务不可用", HttpStatus.SERVICE_UNAVAILABLE.value())));
        } else if (ex instanceof ResponseStatusException) {
            response.setStatusCode(((ResponseStatusException) ex).getStatus());
            return response.writeWith(Mono.just(getResponseBuffer(response, ex.getMessage(), ((ResponseStatusException) ex).getStatus().value())));
        }
        
        // 默认返回内部服务器错误
        response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
        log.error("网关异常: {}", ex.getMessage(), ex);
        return response.writeWith(Mono.just(getResponseBuffer(response, "网关异常: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR.value())));
    }
    
    /**
     * 构建响应数据
     */
    private DataBuffer getResponseBuffer(ServerHttpResponse response, String message, int code) {
        String json = String.format("{\"code\":%d,\"message\":\"%s\",\"data\":null}", code, message);
        byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
        return response.bufferFactory().wrap(bytes);
    }
} 